package com.zt.questionnaire.common.utils;

import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.List;
import java.util.Random;

public class RandomUtil {

    private static final Logger log = LoggerFactory.getLogger(RandomUtil.class);

    /**
     * 获取指定长度的字符串<br>
     *
     * @param count
     * @return
     */
    public static String getRandomCode(int count) {
        return RandomStringUtils.randomAlphanumeric(count).toLowerCase();
    }

    /**
     * random()随机一个大于等于0，小于1的数字
     **/
    public static Random random = new Random(System.currentTimeMillis());

    /**
     * 随机出一个给定范围的值, [min, max](包含最小值和最大值)
     *
     * @param min 最小值
     * @param max 最大值
     * @return
     */
    public static int getRandomNum(int min, int max) {

        return random.nextInt(max + 1 - min) + min;
    }

    public static float getRandomNum(float min, float max) {
        int min1 = (int) (min * 100);
        int max1 = (int) (max * 100);
        int n = getRandomNum(min1, max1);
        return n / 100;

    }

    public static int getRandomNum() {

        return random.nextInt();
    }

    /**
     * 在两个浮点数间随机[min, max]
     *
     * @param min
     * @param max
     * @return
     */
    public static double randomDouble(double min, double max) {
        return getRandomNum(min, max, 3);
    }

    public static double getRandomNum(double min, double max, int floatnum) {

        double pow = Math.pow(10, floatnum);
        int minInt = (int) (min * pow);
        int maxInt = (int) (max * pow);

        int rand = getRandomNum(minInt, maxInt);

        double randfloat = (rand / pow);

        return randfloat;
    }

    /**
     * 随机一个数字
     *
     * @param num1 第一个随机率
     * @param num2 第二个随机率
     * @param pro  比率制度，（10=十分比，100=百分比，1000=千分比……）
     * @return 如果随机到的数字在第一个随机率里面返回1，第二个就返回2，两个都不在，返回0
     */
    public static int getRandomParamNum(int num1, int num2, int pro) {

        int n = random.nextInt(pro);
        if (n < num1) {
            return 1;
        } else if (n >= num1 && n < num2) {
            return 2;
        }
        return 0;
    }

    /**
     * 返回随机数的范围在集合里哪个元素里面的下标,没有在任何一个里面返回-1。 都是百分比制度。
     * 例如：比率分配是：10:50:25:15，list=[10,50,25,15]
     *
     * @param list
     * @param pro  比率制度，（10=十分比，100=百分比，1000=千分比……）
     * @return
     */
    public static int getRandomParamNum(int[] list, int pro) {
        int n = random.nextInt(pro);

        int changeNum = 0;
        for (int i = 0; i < list.length; i++) {
            int currNum = list[i] + changeNum;
            if (n >= changeNum && n < currNum) {
                return i;
            }
            changeNum = currNum;
        }
        return -1;
    }

    /**
     * 返回随机数的范围在集合里哪个元素里面的下标,没有在任何一个里面返回-1。 都是百分比制度。
     * 例如：比率分配是：10:50:25:15，list=[10,50,25,15]
     *
     * @param list
     * @param pro  比率制度，（10=十分比，100=百分比，1000=千分比……）
     * @return
     */
    public static int getRandomParamNum(List<Integer> list, int pro) {
        int n = random.nextInt(pro);
        int changeNum = 0;
        for (int i = 0; i < list.size(); i++) {
            int currNum = list.get(i) + changeNum;
            if (n >= changeNum && n < currNum) {
                return i;
            }
            changeNum = currNum;
        }

        return -1;
    }

    /**
     * 返回随机数的范围在集合里哪个元素里面的下标,没有在任何一个里面返回-1
     *
     * @param list
     * @param floatNum 集合元素最多小数点个数
     * @param pro      比率制度，（10=十分比，100=百分比，1000=千分比……）
     * @return
     */
//	public static int getRandomParamNum(List<Double> list, int floatNum, int pro) {
//		double pow = Math.pow(10, floatNum);
//		int baserand = (int) (pow * pro);
//		int n = random.nextInt(baserand);
//
//		int changeElem = 0;
//		for (int i = 0; i < list.size(); i++) {
//			int elem = (int) (list.get(i) * pow);
//			int sum = changeElem + elem;
//			if (n >= changeElem && n < sum) {
//				return i;
//			}
//			changeElem = sum;
//		}
//
//		return -1;
//	}
    public static int getRandomParamNum(List<Float> list, int floatNum, int pro) {
        double pow = Math.pow(10, floatNum);
        int baserand = (int) (pow * pro);
        int n = random.nextInt(baserand);

        int changeElem = 0;
        for (int i = 0; i < list.size(); i++) {
            int elem = (int) (list.get(i) * pow);
            int sum = changeElem + elem;
            if (n >= changeElem && n < sum) {
                return i;
            }
            changeElem = sum;
        }

        return -1;
    }

    public static int getRandomParamNum(double[] list, int floatnum, int pro) {
        double pow = Math.pow(10, floatnum);
        int baserand = (int) (pow * pro);

        // int n = (int) (Math.random() * baserand);
        int n = random.nextInt(baserand);

        int changeElem = 0;
        for (int i = 0; i < list.length; i++) {
            int elem = (int) (list[i] * pow);
            int sum = changeElem + elem;
            if (n >= changeElem && n < sum) {
                return i;
            }
            changeElem = sum;
        }

        return -1;
    }

    /**
     * 返回随机数的范围在集合里哪个元素里面的下标,没有在任何一个里面返回-1。 都是百分比制度。
     * 例如：比率分配是：10:50:25:15，list=[10,50,25,15]
     *
     * @param list
     * @param pro  比率制度，（10=十分比，100=百分比，1000=千分比……）
     * @return
     *//*
     * public static byte getRandomParamNum(HashMap<Byte, Integer> map,int pro){
     * if(map==null || map.size()==0){ return -1; }
     *
     * int n=random.nextInt(pro); Set<Byte> set = map.keySet(); int before=0;
     * for(byte key:set){ Integer value = map.get(key); int curr=value+before;
     * if(n>=before && n<curr ){ return key; } before=curr; }
     *
     * return -1; }
     *
     * public static int getRandomParamNum1(HashMap<Integer, Integer> map,int pro){
     * if(map==null || map.size()==0){ return -1; }
     *
     * int n=random.nextInt(pro);
     *
     * Set<Integer> set = map.keySet(); int before=0; for(Integer key:set){ Integer
     * value = map.get(key); int curr=value+before; if(n>=before && n<curr ){ return
     * key; } before=curr; }
     *
     * return -1; }
     */

    /**
     * 是否在概率内，true:表示在概率内 ，false:不在概率内
     *
     * @param probability 概率
     * @param floatnum    有几位小数
     * @param pro         比率制度（10=十分比,100=百分比,1000=千分比）
     * @return
     */
    public static boolean isProbability(double probability, int floatnum, int pro) {
        double pow = Math.pow(10, floatnum);
        int baserand = (int) (pow * pro);
        int n = random.nextInt(baserand);

        int elem = (int) (probability * pow);

        if (n < elem) {
            return true;
        }
        return false;
    }

    // 去掉0和O，避免玩家区分不了
    private static String[] chars = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G",
        "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",};
    private static int charsSize = chars.length - 1;

    /**
     * 随机生成一个指定长度的字符,包含数字和字母,去掉0和O，避免玩家区分不了<br>
     * 且开头不为0<br>
     *
     * @param len
     * @return
     */
    public static String getRandomStr(int len) {
        StringBuffer sb = new StringBuffer(len);
        sb.append(chars[RandomUtil.getRandomNum(1, charsSize)]);
        for (int i = 1; i < len; i++) {
            int index = RandomUtil.getRandomNum(0, charsSize);
            sb.append(chars[index]);
        }
        return sb.toString();
    }

    private static String[] nums = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    private static int numsSize = nums.length - 1;

    /**
     * 随机生成一个指定长度的字符,只包含数字<br>
     * 且开头不为0<br>
     *
     * @param len
     * @return
     */
    public static String getRandomNumStr(int len) {
        StringBuffer sb = new StringBuffer(len);
        // 收位数字不能为0
        sb.append(nums[RandomUtil.getRandomNum(1, numsSize)]);
        for (int i = 1; i < len; i++) {
            int index = RandomUtil.getRandomNum(0, numsSize);
            sb.append(nums[index]);
        }
        return sb.toString();
    }

    /**
     * 获取随机的索引值
     *
     * @return
     */
    public static int getIndex(List<Float> list, int floatNum, int pro) {
        int index = RandomUtil.getRandomParamNum(list, floatNum, pro);
        while (index != -1) {
            return index;
        }
        return getIndex(list, floatNum, pro);
    }

    /*
     * public static void main(String[] args) {
     *
     * for(int i=0; i<100; i++) { System.out.println(random.nextFloat()); try {
     * Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
     * }
     *
     * System.out.println(Float.MAX_VALUE);
     *
     * double pow = Math.pow(10, 0);
     *
     * int baserand = (int)(pow * 100);
     *
     * List<Float> list=new ArrayList<Float>(); list.add(5.5f); list.add(10.5f);
     * list.add(20.5f); list.add(40.5f); // int[] list={5,10,20,40};
     * System.out.println(getRandomParamNum(list,1, 100)); // HashMap<Byte, Integer>
     * map=new HashMap<Byte, Integer>(); // map.put(new Byte("1"), 10); //
     * map.put(new Byte("2"), 20); // map.put(new Byte("3"), 40); //
     * System.out.println(getRandomParamNum(map, 100)); }
     */

    public static void main(String[] args) {
//		System.out.println(getRandomCode(2));
        List<Float> redPacketList = Arrays.asList(6.66F, 8.88F, 16.6F, 18.8F, 38.8F, 68.8F, 88.8F);
        List<Float> possibilityList = Arrays.asList(0.29F, 0.26F, 0.22F, 0.13F, 0.06F, 0.03F, 0.01F);

        for (int i = 0; i < 10000; i++) {
            int randomParamNum = getRandomParamNum(possibilityList, 2, 100);
            if (randomParamNum != -1) {

                System.out.println(randomParamNum);
            }
        }
    }
}
